package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.utils.StringUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.constants.RedisConstants;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class LikedRecordServiceRedisImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {
    final RabbitMqHelper mqHelper;
    final StringRedisTemplate redisTemplate;

    @Override
    public void addLikeRecord(LikeRecordFormDTO recordDTO) {
        // 1.获取登录用户
        Long userId = UserContext.getUser();
        Boolean liked = recordDTO.getLiked();
        //2.判断是点赞or取消点赞
        Boolean flag;
        if (liked) {  //2.1点赞-新增记录
            //业务点赞数+1
            flag = like(recordDTO, userId);
        } else {//2.2取消点赞-删除记录
            //业务点赞数-1
            flag = unlike(recordDTO, userId);
        }
        //3.发消息给对应业务，执行更新点赞数
        // 3.如果执行成功，统计点赞总数.
        if (!flag) {
            return;
        }
        //统计该业务被点赞的次数
        Long likedTimes = redisTemplate
                .opsForSet()
                .size(RedisConstants.LIKE_BIZ_KEY_PREFIX + recordDTO.getBizId());
        if (likedTimes == null){
            return;
        }
        /*

        Integer likedTimes = lambdaQuery()
                .eq(LikedRecord::getBizId, recordDTO.getBizId())
                .count();*/
        //点赞次数存入redis key feild value
        String key = RedisConstants.LIKES_TIMES_KEY_PREFIX + recordDTO.getBizType();
    redisTemplate
            .opsForZSet()
            .add(key,recordDTO.getBizId().toString(),likedTimes);

//        // 4.发送MQ通知--消息：业务id+当前业务点赞数
//        mqHelper.send(
//                MqConstants.Exchange.LIKE_RECORD_EXCHANGE,
//                StringUtils.format(MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE, recordDTO.getBizType()),
//                LikedTimesDTO.of(recordDTO.getBizId(), likedTimes.intValue()));
//
   }

    @Override
    public Set<Long> isBizLiked(List<Long> bizIds) {
        // 1.获取登录用户
        Long userId = UserContext.getUser();
        //判断当前业务是否被登陆用户点赞过
        List<LikedRecord> list = lambdaQuery().eq(LikedRecord::getUserId, userId)
                .in(LikedRecord::getBizId, bizIds)
                .list();
        //2.返回结果
        if (list != null && !list.isEmpty()) {
            Set<Long> set = list.stream().map(LikedRecord::getBizId).collect(Collectors.toSet());
            return set;
        }
        return null;
    }

    @Override
    public void readLikedTimesAndSendMessage(String bizType, int maxBizSize) {
        //key
        String key = RedisConstants.LIKES_TIMES_KEY_PREFIX + bizType;
        //读取并删除 缓存中的点赞次数
        Set<ZSetOperations.TypedTuple<String>> popMin = redisTemplate.opsForZSet().popMin(key, maxBizSize);
        List<LikedTimesDTO> list =new ArrayList<>();
        for (ZSetOperations.TypedTuple<String> r : popMin) {

            Double score = r.getScore();
            String value = r.getValue();
            if (score == null || value == null){
                continue;
            }
            LikedTimesDTO of = LikedTimesDTO.of(Long.valueOf(value), score.intValue());
            list.add(of);
        }

        //2.发送MQ通知--消息：list<object>：业务id+当前业务点赞数
                mqHelper.send(
                MqConstants.Exchange.LIKE_RECORD_EXCHANGE,
                StringUtils.format(MqConstants.Key.LIKED_TIMES_KEY_TEMPLATE, bizType),
                        list
               );



    }

    private Boolean unlike(LikeRecordFormDTO recordDTO, Long userId) {

/*        //1.查询是否已经点赞
        LikedRecord record = query().eq("user_id", userId)
                .eq("biz_id", recordDTO.getBizId())
                .eq("biz_type", recordDTO.getBizType())
                .one();
        if (record == null) {
            return false;
        }
        //2.新增记录
        boolean remove = remove(new QueryWrapper<LikedRecord>().eq("user_id", userId).eq("biz_id", recordDTO.getBizId()));
        return remove;*/
        Long remove =
                redisTemplate
                        .opsForSet()
                        .remove(RedisConstants.LIKE_BIZ_KEY_PREFIX + recordDTO.getBizId(), userId.toString());
        return remove!=null&&remove > 0;
    }

    private Boolean like(LikeRecordFormDTO recordDTO, Long userId) {
/*        //1.查询是否已经点赞
        LikedRecord record = query().eq("user_id", userId)
                .eq("biz_id", recordDTO.getBizId())
                .eq("biz_type", recordDTO.getBizType())
                .one();
        if (record != null){
            return false;
        }
        //2.新增记录
        LikedRecord r = new LikedRecord();
        r.setUserId(userId);
        r.setBizId(recordDTO.getBizId());
        r.setBizType(recordDTO.getBizType());
        save(r);
        return true;

    }*/

        //1.新增点赞记录
        //1.key
        String key = RedisConstants.LIKE_BIZ_KEY_PREFIX + recordDTO.getBizId();
        Long flag = redisTemplate.opsForSet().add(key, userId.toString());
        return flag!=null&&flag > 0;

    }
}